package com.zilue.security.service;

import com.zilue.security.util.base64.Base64Util;
import com.zilue.security.util.rsa.RSAUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by zilue on 2017/1/17.
 * 1.签名分两种，一种是普通签名，一种是数字签名
 */
public abstract class RsaPrivateKeyAbstractService extends RsaService {
    public static Logger logger = LoggerFactory.getLogger("security-client");

    private String privateKey;

    /**
     * 加密方式签名（私钥）
     *
     * @param paramterMap
     * @return
     */
    public Map<String, String> signByPrivateKey(Map<String, String> paramterMap) {
        try {
            byte[] privateStr = RSAUtil.encryptByPrivateKey(getDigest(paramterMap), getPrivateKey());
            String sign = Base64Util.encodeByte(privateStr);
            paramterMap.put(this.sign, sign);
        } catch (Exception e) {
            logger.error("私钥加密签名异常：", e);
        }
        return paramterMap;
    }

    /**
     * 加密方式验证签名（私钥）
     *
     * @param paramterMap
     * @return
     */
    public boolean verifyByPrivateKey(Map<String, String> paramterMap) {
        if (!this.status)
            return true;
        try {
            //1.取出签名参数
            String signParamter = paramterMap.get(this.sign);

            //2.复制一个map，移除签名
            Map<String, String> map = new HashMap<String, String>();
            map.putAll(paramterMap);
            map.remove(this.sign);

            //3.将签名解密成原文
            byte[] bytes = Base64Util.decodeByte(signParamter);
            byte[] publicKeyBytes = RSAUtil.decryptByPrivateKey(bytes, getPrivateKey());

            //4.比对原文和摘要原文
            if (new String(publicKeyBytes).equals(getDigest(map)))
                return true;
            else
                return false;
        } catch (Exception e) {
            logger.error("私钥解密签名异常：", e);
            return false;
        }
    }

    /**
     * 数字签名（数字签名只允许私钥签名，公钥验签）
     *
     * @param paramterMap
     * @return
     */
    public Map<String, String> digitalSignature(Map<String, String> paramterMap) {
        try {
            String digitalSignature = RSAUtil.sign(getDigest(paramterMap).getBytes(), getPrivateKey());
            paramterMap.put(this.sign, digitalSignature);
        } catch (Exception e) {
            logger.error("数字签名异常：", e);
        }
        return paramterMap;
    }

    /**
     * 从参数中获取摘要的算法
     *
     * @param paramterMap
     * @return
     */
    public abstract String getDigest(Map<String, String> paramterMap);

    public String getPrivateKey() {
        if (privateKey == null)
            logger.error("未配置私钥，请配置私钥！！");
        return privateKey;
    }

    public void setPrivateKey(String privateKey) {
        this.privateKey = privateKey;
    }

}
